package com.cennavi.bigdata.baotou.scripts;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cennavi.bigdata.baotou.util.PropertiesUtil;
import com.mongodb.*;
import com.navinfo.mapspotter.foundation.util.MercatorUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.LineString;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.FileReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zuoweiguang on 2016/9/19.
 * 脚本功能：将世纪高通提供的rtic路况匹配道路的文档：correspondingOfzhuhai.csv 转换 存储到mongo中
 * 1.将 Corresponding表录入到mongo，并匹配好rtic与link的对应关系
 * 2.生成traffic_status表
 */
public class Corresponding2Mongo_bak20170220 extends ActualTimeRequest{

    private static JSONObject prop = PropertiesUtil.getProperties();
    public SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
    private MongoClient mongoClient = null;
    private DB db = null;
    private DBCollection correspondingCol = null;
    private DBCollection trafficStatusCol = null;

    public Corresponding2Mongo_bak20170220() {
        //获取 mongo 的连接
        ServerAddress serverAddress = new ServerAddress(prop.getString("mongoHost"), prop.getInteger("mongoPort"));
        mongoClient = new MongoClient(serverAddress);
        db = mongoClient.getDB(prop.getString("mongoDb"));
        correspondingCol = db.getCollection("corresponding_t");
        correspondingCol.drop();
        trafficStatusCol = db.getCollection("traffic_status_t");
        trafficStatusCol.drop();
    }

    public void makeCorresponding(String filename) {
        FileReader fileReader = null;
        CSVParser csvFileParser = null;
        //创建CSVFormat（header mapping）
        CSVFormat csvFileFormat = CSVFormat.DEFAULT;
        try {
            //初始化FileReader object
            fileReader = new FileReader(filename);
            csvFileParser = new CSVParser(fileReader, csvFileFormat);
            //CSV文件records
            List<CSVRecord> csvRecords = csvFileParser.getRecords();
            System.out.println("corresponding records total:" + csvRecords.size());
            List<DBObject> objList = new ArrayList<>();
            int count = 0;
            for (int i = 1; i < csvRecords.size(); i++) {
                CSVRecord line = csvRecords.get(i);
                int columeSize = line.size();
//                System.out.println("size:" + columeSize);

                DBObject lineObj = new BasicDBObject();
                List<Integer> linkPidList = new ArrayList<>();
                for (int j = 0; j < columeSize; j ++) {
                    if (j == 0) {
                        int MeshNo = Integer.valueOf(line.get(j));
                        lineObj.put("mesh_code", MeshNo);
                        int RticLinkKind = Integer.valueOf(line.get(j + 1));
                        lineObj.put("rtic_link_kind", RticLinkKind);
                        String RTIC_linkID = line.get(j + 2);
                        String rtic_id = RTIC_linkID.substring(7, RTIC_linkID.length());
                        lineObj.put("rtic_id", String.format("%s%s%s", MeshNo, RticLinkKind, rtic_id));
                    }
                    else if (j >= 6 && j % 2 == 0) {
                        if (null != line.get(j)) {
                            int NILink = Integer.valueOf(line.get(j));
                            linkPidList.add(NILink);
                        }
                    }
                }
                lineObj.put("link_pid_list", linkPidList);
                objList.add(lineObj);
                count += 1;
                if (count % 2000 == 0) {
                    System.out.println("convert mongo count:" + count);
                    //存mongo
                    correspondingCol.insert(objList);
                    objList.clear();
                }
//                System.out.println(lineObj.toString());
            }
            if (objList.size() > 0) {
                correspondingCol.insert(objList);
                objList.clear();
            }
            System.out.println("convert mongo count:" + count);

            //创建索引
            correspondingCol.createIndex("mesh_code");
            correspondingCol.createIndex("rtic_id");
            correspondingCol.createIndex("rtic_link_kind");
            correspondingCol.createIndex("link_pid_list");
            System.out.println("make corresponding index");

            System.out.println("------------- make corresponding done! --------------");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                fileReader.close();
                csvFileParser.close();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                fileReader.close();
                csvFileParser.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void makeTrafficStatus() {
        int count = 0;
        int total = 0;
        try {
            String url = "http://211.151.84.10:9601/TrafficEyeVecService/RticPoint";

            //查询 correspondingOfxian 对应的link_pid
            List<DBObject> bulk = new ArrayList<>();

            BasicDBObject fields = new BasicDBObject();
            fields.append("mesh_code", 1);
            fields.append("rtic_link_kind", 1);
            fields.append("rtic_id", 1);
            DBCursor cursor = correspondingCol.find(new BasicDBObject(), fields).batchSize(30);
            while (cursor.hasNext()) {
                DBObject rtic_info = cursor.next();
                String rtic_id = (String) rtic_info.get("rtic_id");

                for (int j = 10; j <= 17; j ++) {
                    String param = "[{\"MapLevel\":\""+j+"\", \"RticId\":\""+rtic_id+"\"}]";
                    String result = sendPost(url, param);
                    JSONArray resultArray = JSONArray.parseArray(result);

                    for (int i = 0; i < resultArray.size(); i ++) {
                        try {
                            JSONObject jsonObject = resultArray.getJSONObject(i);
                            JSONArray pointList = jsonObject.getJSONArray("Point");
                            if (pointList.size() == 0) {
//                                System.out.println("rtic_id not found:" + rtic_id);
                                continue;
                            }
                            BasicDBObject data = new BasicDBObject();

                            StringBuffer sb = new StringBuffer();
                            sb.append("LINESTRING (");
                            Iterator it = pointList.iterator();
                            while (it.hasNext()) {
                                JSONObject obj = (JSONObject) it.next();
                                String coordinateStr = obj.getString("coordinate");
                                String[] splitCoor = coordinateStr.split(",");
                                sb.append(splitCoor[0] + " "+ splitCoor[1] + ",");
                            }
                            String rticWkt = sb.substring(0, sb.length() - 1);
                            rticWkt = rticWkt + ")";
                            data.put("geometry", rticWkt);

                            data.put("mesh_code", rtic_info.get("mesh_code"));
                            data.put("rtic_link_kind", rtic_info.get("rtic_link_kind"));
                            data.put("rtic_id", rtic_info.get("rtic_id"));

                            data.put("status", 1);
                            data.put("temp_status", 1);
                            data.put("traveltime", "");
                            data.put("updatetime", sdf.format(new Date()));
                            data.put("rtic_updatetime", "");
                            data.put("sectionCntList", new ArrayList<>());
                            data.put("level", j);

                            LineString lineString = (LineString) wktReader.read(rticWkt);
                            Envelope envelope = lineString.getEnvelope().getEnvelopeInternal();
                            //生成tile
                            Coordinate lt = new Coordinate(envelope.getMinX(), envelope.getMaxY());
                            Coordinate rb = new Coordinate(envelope.getMaxX(), envelope.getMinY());
                            //tile级别
//                            for (int k = 7; k <= 17; k++) {
//                                rtic_info.put("tile_" + k, MercatorUtil.bounds2Tiles(lt, rb, k));
//                            }
                            data.put("tile_" + j, MercatorUtil.bounds2Tiles(lt, rb, j));
                            bulk.add(data);
                            count += 1;
                            total += 1;

                            if (count % 500 == 0) {
                                trafficStatusCol.insert(bulk);
                                System.out.println("make rtic count:" + total);
                                bulk.clear();
                                count = 0;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

            }
            //创建索引
            System.out.println("make traffic_status index......");
            trafficStatusCol.createIndex("mesh_code");
            trafficStatusCol.createIndex("rtic_link_kind");
            trafficStatusCol.createIndex("rtic_id");
            for (int k = 10; k <= 17; k++) {
                trafficStatusCol.createIndex("tile_" + k);
            }
            System.out.println("make traffic_status index done!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("make rtic count:" + total);
            System.out.println("-------------- make traffic_status done! --------------");
        }
    }

    private void closeConnection() {
        if (mongoClient != null) {
            mongoClient.close();
        }
    }

    public static void main(String[] args) {
        Corresponding2Mongo_bak20170220 ccm = new Corresponding2Mongo_bak20170220();
        ccm.makeCorresponding("correspondingOfbaotou_160927.csv");
        ccm.makeTrafficStatus();
        ccm.closeConnection();
    }

}
